{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[NbConvertApp] Converting notebook eesardocs.ipynb to slides\n",
      "[NbConvertApp] Writing 264336 bytes to eesardocs.slides.html\n",
      "[NbConvertApp] Redirecting reveal.js requests to https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.5.0\n",
      "Serving your slides at http://127.0.0.1:8000/eesardocs.slides.html\n",
      "Use Control-C to stop this server\n",
      "Neues Fenster in aktueller Browsersitzung erstellt.\n",
      "WARNING:tornado.access:404 GET /custom.css (127.0.0.1) 2.84ms\n",
      "WARNING:tornado.access:404 GET /custom.css (127.0.0.1) 0.89ms\n",
      "WARNING:tornado.access:404 GET /favicon.ico (127.0.0.1) 0.54ms\n",
      "^C\n",
      "\n",
      "Interrupted\n"
     ]
    }
   ],
   "source": [
    "!jupyter nbconvert eesardocs.ipynb --to slides --post serve "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [],
   "source": [
    "import warnings\n",
    "# these are innocuous but irritating\n",
    "warnings.filterwarnings(\"ignore\", message=\"numpy.dtype size changed\")\n",
    "warnings.filterwarnings(\"ignore\", message=\"numpy.ufunc size changed\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Change Detection with Sentinel-1 PolSAR imagery on the GEE\n",
    "\n",
    "### Mort Canty\n",
    "    mort.canty@gmail.com\n",
    "### Joshua Rutkowski, Irmgard Niemeyer \n",
    "    Jülich Forschungszentrum, Germany\n",
    "### Allan A. Nielsen, Knut Conradsen, Henning Skriver\n",
    "    Technical University of Denmark\n",
    "### September 2018"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Software Installation\n",
    "\n",
    " Pull and/or run the container with\n",
    " \n",
    "     docker run -d -p 443:8888 --name=eesar mort/eesardocker \n",
    "     \n",
    " or, if you are on a Raspberry Pi,\n",
    " \n",
    "     docker run -d -p 443:8888 --name=eesar mort/rpi-eesardocker\n",
    "\n",
    "Point your browser to http://localhost:443 to see the Jupyter notebook home page. \n",
    "\n",
    "Open the Notebook \n",
    "\n",
    "    interface.ipynb \n",
    "\n",
    "Stop the container with\n",
    "\n",
    "    docker stop eesar \n",
    "     \n",
    "Re-start with\n",
    "\n",
    "    docker start eesar "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### The GEE Sentinel-1 Archive\n",
    "\n",
    "https://explorer.earthengine.google.com/#detail/COPERNICUS%2FS1_GRD"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Background\n",
    "\n",
    "### Vector and matrix representations\n",
    "\n",
    "A fully polarimetric SAR measures a\n",
    "$2\\times 2$ _scattering matrix_ $S$  at each resolution cell on the ground.\n",
    "The scattering matrix relates the incident and the backscattered\n",
    "electric fields $E^i$ and $E^b$ according to\n",
    "\n",
    "$$\n",
    "\\pmatrix{E_h^b \\cr E_v^b}\n",
    "=\\pmatrix{S_{hh} & S_{hv}\\cr S_{vh} & S_{vv}}\\pmatrix{E_h^i \\cr E_v^i}.\n",
    "$$\n",
    "\n",
    "The per-pixel polarimetric information in the scattering matrix $S$, under the assumption\n",
    "of reciprocity ($S_{hv} = S_{vh}$), can then be expressed as a three-component complex vector\n",
    "\n",
    "$$\n",
    "s = \\pmatrix{S_{hh}\\cr \\sqrt{2}S_{hv}\\cr S_{vv}},\n",
    "$$\n",
    "\n",
    "The total intensity is referred to as the _span_ and is the complex inner product of the vector $s$,\n",
    "\n",
    "$$\n",
    "{\\rm span} = s^\\top s = |S_{hh}|^2 + 2|S_{hv}|^2 + |S_{vv}|^2.\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "The polarimetric signal is  can also be represented by taking the complex outer product of $s$ with itself:\n",
    "\n",
    "$$\n",
    "C = s s^\\top = \\pmatrix{ |S_{hh}|^2 & \\sqrt{2}S_{hh}S_{hv}^* & S_{hh}S_{vv}^* \\cr\n",
    "                                     \\sqrt{2}S_{hv}S_{hh}^* & 2|S_{hv}|^2 & \\sqrt{2}S_{hv}S_{vv}^* \\cr\n",
    "                                     S_{vv}S_{hh}^* & \\sqrt{2}S_{vv}S_{hv}^* & |S_{vv}|^2 }.\n",
    "$$\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Multi-looking\n",
    "\n",
    "The matrix $C$ can be averaged over the number of looks (number of adjacent cells used to average out the effect of speckle) to give an estimate of the __covariance matrix__ of each multi-look pixel:\n",
    "\n",
    "$$\n",
    "\\bar{C}  ={1\\over m}\\sum_{\\nu=1}^m  s(\\nu) s(\\nu)^\\top = \\langle  s s^\\top \\rangle\n",
    " = \\pmatrix{ \\langle |S_{hh}|^2\\rangle & \\langle\\sqrt{2}S_{hh}S_{hv}^*\\rangle & \\langle S_{hh}S_{vv}^*\\rangle \\cr\n",
    "\\langle\\sqrt{2} S_{hv}S_{hh}^*\\rangle & \\langle 2|S_{hv}|^2\\rangle & \\langle\\sqrt{2}S_{hv}S_{vv}^*\\rangle \\cr\n",
    "\\langle S_{vv}S_{hh}^*\\rangle & \\langle\\sqrt{2}S_{vv}S_{hv}^*\\rangle & \\langle |S_{vv}|^2\\rangle },\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Dual polarimetric imagery\n",
    "\n",
    "The Sentinel-1 sensors operate in reduced, power-saving polarization modes, emitting only one polarization and receiving two (dual polarization) or one (single polarization). \n",
    "\n",
    "For vertical transmission and horizontal and vertical reception,\n",
    "\n",
    "$$\n",
    "\\bar{C} = \\pmatrix{ \\langle |S_{vv}|^2\\rangle & \\langle S_{vv}S_{vh}^*\\rangle \\cr\n",
    "\\langle S_{vh}S_{vv}^*\\rangle & \\langle |S_{vh}|^2\\rangle },\n",
    "$$\n",
    "\n",
    "The GEE archives only the diagonal (intensity) matrix elements, so we work in fact with\n",
    "\n",
    "$$\n",
    "\\bar{C} = \\pmatrix{ \\langle |S_{vv}|^2\\rangle & 0 \\cr\n",
    "0  & \\langle |S_{vh}|^2\\rangle },\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "\n",
    "### Change detection, bitemporal imagery\n",
    "\n",
    "The probability distribution of $\\bar C$ is completely determined by the parameter $\\Sigma$ (the covariance matrix) and by the __equivalent number of looks__ ENL. \n",
    "\n",
    "Given two measurements of polarized backscatter, one can set up an hypothesis test in order to decide whether or not a change has occurred. \n",
    "\n",
    " $$H_0: \\Sigma_1 = \\Sigma_2$$ \n",
    " \n",
    " i.e., the two observations were sampled from the same distribution and no change has occurred\n",
    " \n",
    " $$H_1: \\Sigma_1\\ne\\Sigma_2$$\n",
    " \n",
    " in other words, there was a change.\n",
    " \n",
    "Since the distributions are known, a test statistic can be formulated which allows one to decide to a desired degree of significance whether or not to reject the null hypothesis. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Change detection, multitemporal imagery\n",
    "\n",
    "In the case of $k > 2$ observations this procedure can be generalized to test a null hypothesis that all of the $k$ pixels are characterized by the same $\\Sigma$, against the alternative that at least one of the $\\Sigma_i$, $i=1\\dots k$, are different, i.e., that at least one change has taken place. \n",
    "\n",
    "\n",
    "Furthermore this so-called  __omnibus test procedure__ can be factored into a sequence of  tests involving hypotheses of the form:\n",
    "\n",
    "$\\Sigma_1 = \\Sigma_2$ against $\\Sigma_1 \\ne \\Sigma_2$,\n",
    "\n",
    "$\\Sigma_1 = \\Sigma_2 = \\Sigma_3$ against $\\Sigma_1 = \\Sigma_2 \\ne \\Sigma_3$,\n",
    "\n",
    "and so forth. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Denoting the test statistics $R^\\ell_j,\\ \\ell = 1\\dots k-1,\\ j=\\ell+1\\dots k$, for a series of, say, $k=5$ images, we have the following tests to consider\n",
    "\n",
    "$$\n",
    "\\matrix{\n",
    "\\ell/j &2 &3 &4 &5\\cr\n",
    "1 & R^1_2 & R^1_3 & R^1_4 & R^1_5 \\cr\n",
    "2 &       & R^2_3 & R^2_4 & R^2_5 \\cr\n",
    "3 &       &       & R^3_4 & R^3_5 \\cr\n",
    "4 &       &       &       & R^4_5 }\n",
    "$$      "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## The GEE interface\n",
    "\n",
    "The interface is programmed against the GEE Python API and uses Jupyter widgets to generate the desired Sentinel-1 times series for processing.\n",
    "\n",
    "Results (changes maps) can be previewed on-the-fly and then exported to the GEE Code Editor for visualization and animation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "58f2af2d05bb4a33a899a6c8621063f3",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "TWFwKGJhc2VtYXA9eyd1cmwnOiAnaHR0cHM6Ly97c30udGlsZS5vcGVuc3RyZWV0bWFwLm9yZy97en0ve3h9L3t5fS5wbmcnLCAnbWF4X3pvb20nOiAxOSwgJ2F0dHJpYnV0aW9uJzogJ01hcCDigKY=\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "6d9e5ea7a77745129e52ccc27fd1c441",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "VkJveChjaGlsZHJlbj0oVGV4dGFyZWEodmFsdWU9dSdBbGdvcml0aG0gb3V0cHV0Jywgcm93cz0zKSwgSEJveChjaGlsZHJlbj0oVGV4dCh2YWx1ZT11JzIwMTctMDQtMDEnLCBkZXNjcmlwdGnigKY=\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from auxil.eeSar_seq import run\n",
    "run()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
